package my.mall.front.api.service.sms

import com.aliyun.dysmsapi20170525.Client
import com.aliyun.dysmsapi20170525.models.SendSmsRequest
import com.aliyun.teaopenapi.models.Config
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import my.mall.common.annotation.Slf4j
import my.mall.common.annotation.Slf4j.Companion.log
import my.mall.common.enums.RespMetaEnum
import my.mall.common.exception.InitException
import my.mall.common.pojo.CommonResp
import my.mall.common.util.RespUtils.success
import my.mall.common.util.RespUtils.warning
import my.mall.db.entity.User
import my.mall.db.service.IUserService
import my.mall.front.api.enums.UserStatus
import org.springframework.stereotype.Service
import java.time.LocalDateTime
import java.util.concurrent.ThreadLocalRandom

@Slf4j
@Service
class AliSmsService(
    private val userService: IUserService
) : SmsService {

    private var client: Client

    init {
        val config = Config()
            .setAccessKeyId(ACCESS_KEY_ID) // 必填，您的 AccessKey Secret
            .setAccessKeySecret(ACCESS_KEY_SECRET)
        config.endpoint = "dysmsapi.aliyuncs.com"
        client = try {
            Client(config)
        } catch (e: Exception) {
            AliSmsService.log.error("init ali sms client failed", e)
            throw InitException(e)
        }
    }

    override fun sendMsg(phoneNum: Long): CommonResp<*> {
        var user = userService.getOne(
            QueryWrapper<User>()
                .select(User.ID, User.USER_STATUS, User.SMS_CODE, User.SMS_TIME)
                .eq(User.PHONE_NUM, phoneNum)
        )
        if (user != null && UserStatus.NORMAL.code != user.userStatus) {
            return warning<Any>(RespMetaEnum.USER_FROZEN)
        }
        if (user?.smsTime != null && user.smsTime!!.isAfter(LocalDateTime.now().minusMinutes(1))) {
            return warning(400, "请勿频繁获取验证码")
        }
        val code = ThreadLocalRandom.current().nextInt(899999) + 100000
        try {
            val sendSmsRequest = SendSmsRequest()
                .setTemplateCode("SMS_154950909")
                .setSignName("阿里云短信测试")
                .setTemplateParam("{\"code\":$code}")
                .setPhoneNumbers(phoneNum.toString())
            val sendSmsResponse = client.sendSms(sendSmsRequest)
            if (200 != sendSmsResponse.getStatusCode()) {
                return warning(400, "验证码发送失败，请重试")
            }
            val responseBody = sendSmsResponse.getBody()
            if ("OK" != responseBody.getCode()) {
                return warning(400, "验证码发送失败，请重试")
            }
        } catch (e: Exception) {
            log.error("send msg failed", e)
            return warning<Any>(RespMetaEnum.TIMEOUT)
        }
        if (user != null) {
            user.smsCode = code
            user.smsTime = LocalDateTime.now()
            userService.updateSmsCode(user)
        } else {
            user = User()
            user.phoneNum = phoneNum
            user.smsCode = code
            user.smsTime = LocalDateTime.now()
            userService.save(user)
        }
        return success()
    }

    companion object {
        private const val ACCESS_KEY_ID = "LTAI4GEhv91a9mPaus6pbEaQ"
        private const val ACCESS_KEY_SECRET = "Kq207ek7oEm6JQbL77fwPQBjh351jt"
    }
}
